import * as THREE from 'three'
import { gui } from '../gui'
import { stats } from '../stats'

type cameraType = THREE.OrthographicCamera|THREE.PerspectiveCamera

function createCourse08 (dom: HTMLElement) {
  const scene = new THREE.Scene()
  // var camera = new PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);
  let camera: cameraType = new THREE.OrthographicCamera(dom.offsetWidth / -8, dom.offsetWidth / 8, dom.offsetHeight / 8, dom.offsetHeight / -8, 50, 100)

  const render = new THREE.WebGLRenderer()
  render.setClearColor(new THREE.Color(0x000000))
  render.setSize(dom.offsetWidth, dom.offsetHeight)
  render.shadowMap.enabled = true

  dom.appendChild(render.domElement)

  // show axes in the screen
  const axes = new THREE.AxesHelper(50)
  scene.add(axes)

  const planeGeometry = new THREE.PlaneGeometry(100, 100)
  const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xAAAAAA })
  const plane = new THREE.Mesh(planeGeometry, planeMaterial)

  plane.rotation.x = -0.5 * Math.PI
  plane.position.set(15, 0, 0)
  plane.receiveShadow = true

  scene.add(plane)

  camera.position.x = -30
  camera.position.y = 40
  camera.position.z = 30
  camera.lookAt(scene.position)

  const spotLight = new THREE.SpotLight(0xFFFFFF)
  spotLight.position.set(-60, 40, -65)
  spotLight.castShadow = true
  spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024)
  spotLight.shadow.camera.far = 130
  spotLight.shadow.camera.near = 40

  scene.add(camera)
  // If you want a more detailled shadow you can increase the
  // mapSize used to draw the shadows.
  // spotLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
  scene.add(spotLight)

  const ambienLight = new THREE.AmbientLight(0xcccccc)
  scene.add(ambienLight)

  for (let i = 0; i < (planeGeometry.parameters.height / 5); i++) {
    for (let j = 0; j < (planeGeometry.parameters.width / 5); j++) {
      const cubeGeo = new THREE.BoxGeometry(4, 4, 4)
      const cubeMaterial = new THREE.MeshLambertMaterial()
      cubeMaterial.color = new THREE.Color(0, Math.random() * 0.25 + 0.5, 0)
      const cube = new THREE.Mesh(cubeGeo, cubeMaterial)

      cube.position.x = -(planeGeometry.parameters.width / 2) + 15 + (i * 5)
      cube.position.y = 2
      cube.position.z = -(planeGeometry.parameters.height / 2) + 5 + (j * 5)

      scene.add(cube)
    }
  }

  const ctrlObj = {
    showText: '透视投影摄像机',
    changeCamera: function () {
      if (camera instanceof THREE.PerspectiveCamera) {
        camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500)
        camera.position.x = -30
        camera.position.y = 40
        camera.position.z = 30
        camera.lookAt(scene.position)
        this.showText = '正交投影摄像机'
      } else {
        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
        camera.position.x = -30
        camera.position.y = 40
        camera.position.z = 30
        camera.lookAt(scene.position)
        this.showText = '透视投影摄像机'
      }
    }
  }

  gui.add(ctrlObj, 'showText').listen()
  gui.add(ctrlObj, 'changeCamera')

  const geometry = new THREE.BoxGeometry(8, 8, 8)
  const material = new THREE.MeshLambertMaterial({ color: 0xff2288 })
  const cube = new THREE.Mesh(geometry, material)
  cube.position.x = 0
  cube.position.y = 8
  cube.position.z = 0
  scene.add(cube)

  render.setAnimationLoop(animation)

  const pos = 0
  function animation () {
    stats.update()
    // pos += 0.01;
    cube.position.x = 10 + (100 * (Math.sin(pos)))
    camera.lookAt(cube.position)
    render.render(scene, camera)
  }

  return { camera, render, scene }
}

export {
  createCourse08
}
